{
  LW Human Interface -- Human Interface input/output with LightWave

  A device being connected is a state handled by the device and its underlying driving mechanism.
  For example, a device may be powered on, but a bluetooth or network connection to it may not be
  operational.  When the device is actually available to get data in/out of the LightWave Human
  Interface system, then it should notify the system that the device is connected.
  Similarly, if the device loses power (low batteries) or its communication with the underlying driving
  mechanism is severed, then the LightWave Human Interface system should be told the device is disconnected.

  Starting and Stopping a device is handled independent of its behind-the-scenes connected state.
  However, only a started device should be concerned with notifying the LightWave Human Interface
  system of its connected state.  Therefore, once a device has been told to start, it must tell the the system
  that it is connected before I/O can pass through it.  The device does not need to indicate when it is disconnected
  after being told to stop, though.

  A device manager that is told to start should add devices for all those that it knows of at that time.
  As devices come and go, they can be added/removed.
  Each device that is added and started will be told to start.
  Each device that is started and removed will be told to stop.

  There may be two ways to interpret configuaritons: 1) the user has a choice from the application; 2) the user manipualtes the
  device directly.  The latter seems the most useful: a real world device may have a switch to change modes of operation;
  a logical device, like a touch screen panel, may have a menu of choices known to the device.  Rarely, if ever, do I foresee
  the user wanting to change the configuration from within LightWave.

  Based on lwhumaninterface.h which is:
  Copyright 2011, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}

unit LW_HumanInterface;

{$mode objfpc}{$H+}

interface

uses
  LW_Types   ,
  LW_Handler ,
  LW_Server  ;

const
  { The manager class provides access to devices. }
  LWHUMANINTERFACE_MANAGER_HCLASS  = 'LWHumanInterfaceManagerHandler'   ;
  LWHUMANINTERFACE_MANAGER_ICLASS  = 'LWHumanInterfaceManagerInterface' ;
  LWHUMANINTERFACE_MANAGER_GCLASS  = 'LWHumanInterfaceManagerGizmo'     ;
  LWHUMANINTERFACE_MANAGER_VERSION = 1 ;

  LWHUMANINTERFACE_DEVICE_VERSION  = 1 ;

  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_UNKNOWN        = 0 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_SIGNED_INT8    = 1 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_UNSIGNED_INT8  = 2 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_SIGNED_INT16   = 3 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_UNSIGNED_INT16 = 4 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_SIGNED_INT32   = 5 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_UNSIGNED_INT32 = 6 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_FLOAT32        = 7 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_FLOAT64        = 8 ;
  LWHUMANINTERFACE_TRACK_RECORD_FORMAT_BOOL           = 9 ;

  // change to configuration
  LWHUMANINTERFACE_NOTIFY_CONFIGURATION               = 1 ;
  // connection has been made
  LWHUMANINTERFACE_NOTIFY_CONNECTED                   = 2 ;
  // connection has been broken
  LWHUMANINTERFACE_NOTIFY_DISCONNECTED                = 3 ;

  LWHUMANINTERFACE_IMAGE_PURPOSE_GENERAL              = 0 ;
  LWHUMANINTERFACE_IMAGE_PURPOSE_NODE                 = 1 ;
  LWHUMANINTERFACE_IMAGE_PURPOSE_SETTINGS             = 2 ;


type

  PLWString = Pointer ; // (need something when our string object is available (in lwstring.h?))

  PLWHumanInterfaceManager = Pointer         ;
  PLWHumanInterfaceDevice  = Pointer         ;
  PLWHumanInterfaceTrack   = Pointer         ;
  PLWDeviceTrack           = PUInt32         ;
  PLWTrackRecord           = PWord           ;
  PPLWTimeStampMS          = ^PLWTimeStampMS ;
  PLWTimeStampMS           = ^TLWTimeStampMS ;
  TLWTimeStampMS           = UInt32  ; // Timestamps are in milliseconds, up to 1000 samples per second uniqueness

  // Track Access
  PLWHumanInterfaceTrackAccess = ^TLWHumanInterfaceTrackAccess;
  TLWHumanInterfaceTrackAccess = record
    // Create a track.  Storage of the track is up to the client-side device
    CreateTrack  : function
                   (      InDeviceID     : PLWHumanInterfaceDevice ;
    			  InTrackID      : PLWDeviceTrack          ;
                    const InDisplayName  : PChar                   ;
                          InRecordFormat                           ,
                          InEventDriven  : Integer                 ) : PLWHumanInterfaceTrack ;

    // Destroy the given track.  Storage of the track is up to the client-side device
    DestroyTrack : procedure
                   (      InTrack : PLWHumanInterfaceTrack         ) ;

    // Obtain the next available RecordID to be filled.
    Advance      : function
                   (      InTrack : PLWHumanInterfaceTrack         ) : PLWTrackRecord         ;

    // Obtain the RecordID of the earliest available record
    Earliest     : function
                   (      InTrack : PLWHumanInterfaceTrack         ) : PLWTrackRecord         ;

    // Obtain the RecordID of the latest available record
    Latest       : function
                   (      InTrack : PLWHumanInterfaceTrack         ) : PLWTrackRecord         ;

    // Obtain the next RecordID after the given RecordID
    Next         : function
                   (      InTrack : PLWHumanInterfaceTrack         ;
    		          InRecord : PLWTrackRecord                ) : PLWTrackRecord         ;

    // Obtain the previous RecordID before the given RecordID
    Previous     : function
                   (      InTrack : PLWHumanInterfaceTrack         ;
                          InRecord : PLWTrackRecord                ) : PLWTrackRecord         ;

    // Set the byte size of each record buffer and the number of records for a track
    SetSize      : procedure
                   (      InTrack : PLWHumanInterfaceTrack         ;
                          InRecordSize : UInt32	                   ;
                          InNumRecords : Word                      ) ;

    // Obtain the byte size of each record buffer and the number of record for a track.
    GetSize      : procedure
                   (      InTrack       : PLWHumanInterfaceTrack   ;
                          OutRecordSize : PUInt32                  ;
                          OutNumRecords : PWord                    ) ;

    // Obtain direct access to the buffer for a given record.
    Access       : function
                   (      InTrack : PLWHumanInterfaceTrack         ;
                          InRecord : PLWTrackRecord                ;
                          OutDataPtr : PPByte                      ;
                          OutTimestampPtr : PPLWTimeStampMS        ) : Integer                ;

    // Obtain the device for this track
    Device       : function
                   (      InTrack : PLWHumanInterfaceTrack         ) : PLWHumanInterfaceDevice ;
  end;

  PLWHumanInterfaceDeviceAccess = ^TLWHumanInterfaceDeviceAccess;
  TLWHumanInterfaceDeviceAccess = record
    // Access to host-side track functions
    TrackAccess   : PLWHumanInterfaceTrackAccess ; // const

    // Obtain the manager for this device
    Manager       : function
    		    (      InDeviceID     : PLWHumanInterfaceDevice ) : PLWHumanInterfaceManager ;

    // Notify the human interface system of a change it would be interested in.  see the LWHUMANINTERFACE_NOTIFY_... defines.
    Notify        : procedure
                    (      InDeviceID     : PLWHumanInterfaceDevice ;
                           InNotification : Integer                 ) ;

    // Adds an already created track as an input track for the device.
    AddInputTrack : procedure
                    (      InDeviceID     : PLWHumanInterfaceDevice ;
                           InTrackID      : PLWHumanInterfaceTrack  ) ;

    // Adds an already created track as an output track for the device.
    AddOutputTrack  : procedure
                    (      InDeviceID     : PLWHumanInterfaceDevice ;
                           InTrackID      : PLWHumanInterfaceTrack  ) ;

    // returns the number of input tracks supported.
    CountInputTracks     : function
    		           (      InDeviceID     : PLWHumanInterfaceDevice ) : UInt32                 ;

    // Input track access (returns 0 for non-existent tracks)
    // The client is responsible for track storage access.
    GetInputTrackAtIndex : function
    			   (      InDeviceID     : PLWHumanInterfaceDevice ;
    				  InIndex        : UInt32                  ) : PLWHumanInterfaceTrack ;

    // Find the track handle for a given track identifier
     FindInputTrack   : function
    		        (  InDeviceID     : PLWHumanInterfaceDevice  ;
    		 	  InTrackID      : PLWHumanInterfaceTrack   ) : PLWHumanInterfaceTrack ;

    // Returns the number of output tracks supported.
    CountOutputTracks : function
                        (  InDeviceID     : PLWHumanInterfaceDevice  ) : UInt32                 ;

    // Output track access (returns 0 for non-existent tracks)
    GetOutputTrackAtIndex : function
    			    (      InDeviceID     : PLWHumanInterfaceDevice ;
    			           InIndex        : UInt32                  )  : PLWHumanInterfaceTrack ;

    // find the track handle for a given track identifier
    FindOutputTrack   : function
    		        (      InDeviceID     : PLWHumanInterfaceDevice ;
    			       InTrackID      : PLWHumanInterfaceTrack  ) : PLWHumanInterfaceTrack ;

    // Get the instance returned by the handler's create routine.
     GetHandlerInstance : function
    			  (      InDeviceID   : PLWHumanInterfaceDevice ) : PLWInstance;
  end;


  // A custom device handler must supply these routines
  // Forward declaration
  PLWHumanInterfaceDeviceHandler = ^TLWHumanInterfaceDeviceHandler;

  PLWHumanInterfaceManagerAccess = ^TLWHumanInterfaceManagerAccess;
  TLWHumanInterfaceManagerAccess = record
    // Access to host-side device functions
    Device_access   : PLWHumanInterfaceDeviceAccess ; // const

    // Create a handler using the given activation function for a specific version
    // CreateDeviceHandler : function
    //                       (      InDeviceActivation : ActivateFunc  ;
    //  					        Version            : Integer       ) : PLWHumanInterfaceDeviceHandler ;

    // Create an instance of a device attached to the provided manager and handled by the given handler
     RegisterDevice  : function
    	               (      InManagerID : PLWHumanInterfaceManager       ;
    		              InHandler	  : PLWHumanInterfaceDeviceHandler ;
    		              Context 	  : Pointer                        ) : PLWHumanInterfaceDevice ;

    // Destroy the given device
    UnregisterDevice : procedure
                       (      InDeviceID  : PLWHumanInterfaceDevice        ) ;

    // Notify the human interface system of a change it would be interested in.
    // See the LWHUMANINTERFACE_NOTIFY_... defines.
    Notify           : procedure
    	               (      InManagerID : PLWHumanInterfaceManager       ;
                              InNotification : Integer	                   ) ;
  end;

  // A device handler create is passed this structure to help it create its device as intended.
  // The create routine should return 0 if an instance could not be created for it.
  PLWHumanInterfaceDeviceCreateContext = ^TLWHumanInterfaceDeviceCreateContext;
  TLWHumanInterfaceDeviceCreateContext = record

    // The device id is useful when accessing the device
    Device        : PLWHumanInterfaceDevice       ;

    // Access to the device
    DeviceAccess  : PLWHumanInterfaceDeviceAccess ;

    // The context is the same as passed into the registerDevice manager access call.
    Context       : Pointer                       ;
  end;

  // A custom device handler must supply these routines
  TLWHumanInterfaceDeviceHandler = record
    Inst        : PLWInstanceFuncs ;

    // create context is a LWHumanInterfaceDeviceCreateContext structure.

    // start the device (make it send/receive).  Return 0 if failed to start, else 1
    // The provided access structure is valid until the device is stopped.

    Start     : function
                (       InInst : PLWInstance ) : Integer ;

    // Configure the device (setup input/output tracks)
    Configure : function
                (       InInst : PLWInstance ) : Integer ;

    // Transfer output tracks data to device.
    Flush     : function
                (       InInst : PLWInstance ) : Integer ;

    // Stop the device (make it stop send/receive).
    // Return 0 if failed to start, else 1
    Stop      : function
                (       InInst : PLWInstance ) : Integer ;

    // Return the unique signature for the device
    Signature : function
                (       InInst : PLWInstance ) : PChar ; // const

    // Fill in a pixel map to represent the device
    // A hint of its purpose is provided so that the handler can supply the most appropriate image.
    // (see LWHUMANINTERFACE_IMAGE_PURPOSE_... defines for available purposes)
    Image     : function
                (       InInst    : PLWInstance ;
                        InPurpose : Integer     ;
                        OutPixmap : PLWPixmap   ) : Integer ;

    // Obtain a user interface to manipulate this device
    // Only modal panels are presently supported via the options member of LWInterface.
    UserInterface : function
                    (       InInst      : PLWInstance ;
                            InInterface : PLWInterface     ;
                            InVersion   : Integer   ) : Integer ;

  end;

  // A custom manager must supply these routines
  PLWHumanInterfaceManagerHandler = ^TLWHumanInterfaceManagerHandler;
  TLWHumanInterfaceManagerHandler = record
    Inst        : PLWInstanceFuncs ;

    // create context is a LWHumanInterfaceDeviceCreateContext structure.

    // start the manager (devices it finds must be added).  Return 0 if failed to start, else 1
    // The provided access structure is valid until the manager is stopped.
    Start     : function
                (       InInst : PLWInstance ) : Integer ;

    // Configure the manager while it is started
    Configure : function
                (       InInst   : PLWInstance ;
                        InAccess : PLWHumanInterfaceManagerAccess ) : Integer ;

    // stop the manager (devices it has added must be removed).
    // Return 0 if failed to stop, else 1
    Stop      : function
                (       InInst : PLWInstance ) : Integer ;

    // Return the unique signature for the device
    Signature : function
                (       InInst : PLWInstance ) : PChar ; // const

    // fill in a pixel map to represent the device
    // A hint of its purpose is provided so that the handler can supply the most appropriate image.
    // (see LWHUMANINTERFACE_IMAGE_PURPOSE_... defines for available purposes)
    Image     : function
                (       InInst    : PLWInstance ;
                        InPurpose : Integer     ;
                        OutPixmap : PLWPixmap   ) : Integer ;
  end;

implementation

end.

